#!/usr/bin/env python3
# _*_coding:utf-8 _*_
__author__ = "Gao"
from django.shortcuts import render
from django.shortcuts import redirect
from django.shortcuts import HttpResponse
from django.http import Http404
from django.urls import reverse
import json
import subprocess
from urllib import parse

from repoistory import models
from ..libs.forms import ProjectCreateForm
from ..libs.forms import ProjectEditForm
from ..libs.forms import BranchCreateForm
from ..libs.forms import BranchEditForm
from ..libs.forms import SubModulCreateForm
from ..libs.forms import SubModulEditForm
from ..libs.forms import ConfigrationCreateForm
from ..libs.forms import ConfigrationEditForm
from ..libs.forms import SubModul2HostCreateForm
from ..libs.forms import SubModul2HostEditForm





def preview(request):
    '''Git项目总揽'''
    if request.method == 'GET':
        res_dict = {'query_set':models.Project.objects.all().values('id','name','description')}
        return render(request, 'backend/Project/preview.html', res_dict)


def add(request):
    '''新增项目'''
    if request.method == 'GET':
        form_obj = ProjectCreateForm()
    elif request.method == 'POST':
        form_obj = ProjectCreateForm(request.POST)
        if form_obj.is_valid():
            models.Project.objects.create(**form_obj.cleaned_data)
            return redirect('/backend/Project/preview/')
    res_dict = {'form_obj': form_obj}
    return render(request, 'backend/Project/change.html', res_dict)


def change(request, nid):
    '''修改项目信息'''
    project_obj = models.Project.objects.filter(id=nid).first()
    if not project_obj:
        raise Http404
    if request.method == 'GET':
        initial = {'id': project_obj.id,
                    'name': project_obj.name,
                    'description': project_obj.description,
                    'git_address': project_obj.git_address,
                    'auth': project_obj.auth,}
        form_obj = ProjectEditForm(initial=initial)
    elif request.method == 'POST':
        form_obj = ProjectEditForm(request.POST)
        if form_obj.is_valid():
            project_obj.name = form_obj.cleaned_data['name']
            project_obj.description = form_obj.cleaned_data['description']
            project_obj.git_address = form_obj.cleaned_data['git_address']
            project_obj.auth = form_obj.cleaned_data['auth']
            project_obj.save()
            return redirect('/backend/Project/preview/')
    res_dict = {'form_obj': form_obj}
    return render(request, 'backend/Project/change.html', res_dict)


def test_git(request):
    '''测试Git认证'''
    if request.method == 'POST':
        res_dict = {'status': True, 'error': None, 'data': None}
        git_address = request.POST.get('git_address').strip()
        auth_id = request.POST.get('auth').strip()
        auth = models.Auth.objects.filter(id=auth_id).first()
        if not git_address or not auth:
            res_dict['status'] = False
        else:
            git_address = parse.urlsplit(git_address)
            schema = git_address.scheme
            netloc = git_address.netloc
            path = git_address.path
            name = auth.name
            password = auth.password
            git_url = '{schema}://{name}:{password}@{netloc}{path}'.format(schema=schema,name=name,password=password,netloc=netloc,path=path)
            test_cmd = 'git ls-remote -h {git_url} HEAD'.format(git_url=git_url)
            test_res = subprocess.getstatusoutput(test_cmd)
            if test_res[0] == 128:
                error_msg = test_res[1].replace(name + ':' + password + '@', '')
                res_dict['status'] = False
                res_dict['error'] = error_msg
        return HttpResponse(json.dumps(res_dict))


def project_manage(request,nid):
    '''项目管理'''
    project = models.Project.objects.filter(id=nid).first()
    if not project:
        raise Http404
    res_dict = {'project': project}
    return render(request, 'backend/Project/manage.html', res_dict)


def branch_preview(request,nid):
    '''项目分支总览'''
    project_obj = models.Project.objects.filter(id=nid).first()
    if not project_obj:
        raise Http404
    res_dict = {'project': project_obj,
                'query_set': models.Branch.objects.filter(project_id=project_obj.id)}
    return render(request, 'backend/Project/branch/preview.html', res_dict)


def branch_add(request,nid):
    '''新增项目分支'''
    project_obj = models.Project.objects.filter(id=nid).first()
    if not project_obj:
        raise Http404
    if request.method == 'GET':
        initial = {'project_id': project_obj.id,}
        form_obj = BranchCreateForm(initial=initial)
    elif request.method == 'POST':
        form_obj = BranchCreateForm(request.POST)
        if form_obj.is_valid():
            models.Branch.objects.create(**form_obj.cleaned_data)
            redirect_url = reverse('branch_preview',kwargs={'nid': project_obj.id})
            return redirect(redirect_url)
    res_dict = {'project': project_obj,
                'form_obj': form_obj}
    return render(request, 'backend/Project/branch/change.html', res_dict)


def branch_change(request, project_id, branch_id):
    '''修改项目分支'''
    project_obj = models.Project.objects.filter(id=project_id).first()
    branch_obj = models.Branch.objects.filter(id=branch_id).first()
    if not project_obj or not branch_obj:
        raise Http404
    if request.method == 'GET':
        initial = {'project_id': project_obj.id,
                   'id': branch_obj.id,
                   'branch': branch_obj.branch,
                   'description':branch_obj.description}
        form_obj = BranchEditForm(initial=initial)
    elif request.method == 'POST':
        form_obj = BranchEditForm(request.POST)
        if form_obj.is_valid():
            branch_obj.branch = form_obj.cleaned_data['branch']
            branch_obj.description = form_obj.cleaned_data['description']
            branch_obj.save()
            redirect_url = reverse('branch_preview', kwargs={'nid': project_obj.id})
            return redirect(redirect_url)
    res_dict = {'project': project_obj,
                'form_obj': form_obj}
    return render(request, 'backend/Project/branch/change.html', res_dict)


def build_command(request, project_id):
    '''打包命令管理'''
    project_obj = models.Project.objects.filter(id=project_id).first()
    if not project_obj:
        raise Http404
    if request.method == 'GET':
        pass
    elif request.method == 'POST':
        project_obj.build_command = request.POST.get('build_command')
        project_obj.save()
    res_dict = {'project': project_obj}
    return render(request, 'backend/Project/build_command.html', res_dict)


def submodul_preview(request, project_id):
    '''子模块总览'''
    project_obj = models.Project.objects.filter(id=project_id).first()
    if not project_obj:
        raise Http404
    res_dict = {'project': project_obj,
                'query_set': models.SubModul.objects.filter(project_id=project_obj.id)}
    return render(request, 'backend/Project/submodul/preview.html', res_dict)


def submodul_add(request, project_id):
    '''新增子模块'''
    project_obj = models.Project.objects.filter(id=project_id).first()
    if not project_obj:
        raise Http404
    if request.method == 'GET':
        initial = {'project_id': project_obj.id}
        form_obj = SubModulCreateForm(initial=initial)
    elif request.method == 'POST':
        form_obj = SubModulCreateForm(request.POST)
        if form_obj.is_valid():
            models.SubModul.objects.create(**form_obj.cleaned_data)
            redirect_url = reverse('submodul_preview', kwargs={'project_id': project_obj.id})
            return redirect(redirect_url)
    res_dict = {'project': project_obj, 'form_obj': form_obj}
    return render(request,'backend/Project/submodul/change.html',res_dict)


def submodul_change(request, project_id,submodul_id):
    project_obj = models.Project.objects.filter(id=project_id).first()
    submodul_obj = models.SubModul.objects.filter(id=submodul_id).first()
    if not project_obj or not submodul_obj:
        raise Http404
    if request.method == 'GET':
        initial = {'project_id': project_obj.id,
                   'id': submodul_obj.id,
                   'order': submodul_obj.order,
                   'name': submodul_obj.name,
                   'description':submodul_obj.description,
                   'source_file': submodul_obj.source_file,
                   'target_file': submodul_obj.target_file,
                   'backup_command': submodul_obj.backup_command,
                   'stop_command': submodul_obj.stop_command,
                   'start_command': submodul_obj.start_command,
                   'clean_old_file_command': submodul_obj.clean_old_file_command}
        form_obj = SubModulEditForm(initial=initial)
    elif request.method == 'POST':
        form_obj = SubModulEditForm(request.POST)
        if form_obj.is_valid():
            submodul_obj.name = form_obj.cleaned_data['name']
            submodul_obj.description = form_obj.cleaned_data['description']
            submodul_obj.source_file = form_obj.cleaned_data['source_file']
            submodul_obj.target_file = form_obj.cleaned_data['target_file']
            submodul_obj.backup_command = form_obj.cleaned_data['backup_command']
            submodul_obj.stop_command = form_obj.cleaned_data['stop_command']
            submodul_obj.start_command = form_obj.cleaned_data['start_command']
            submodul_obj.clean_old_file_command = form_obj.cleaned_data['clean_old_file_command']
            submodul_obj.save()
            for host in submodul_obj.submodul2host_set.all():
                if not host.is_customize:
                    host.source_file = submodul_obj.source_file
                    host.target_file = submodul_obj.target_file
                    host.backup_command = submodul_obj.backup_command
                    host.stop_command = submodul_obj.stop_command
                    host.start_command = submodul_obj.start_command
                    host.clean_old_file_command = submodul_obj.clean_old_file_command
                    host.save()

            redirect_url = reverse('submodul_preview', kwargs={'project_id': project_obj.id})
            return redirect(redirect_url)
    res_dict = {'project': project_obj,
                'form_obj': form_obj}
    return render(request,'backend/Project/submodul/change.html',res_dict)


def submodul_manage(request,project_id,submodul_id):
    '''子模块管理'''
    project_obj = models.Project.objects.filter(id=project_id).first()
    submodul_obj = models.SubModul.objects.filter(id=submodul_id).first()
    if not project_obj or not submodul_obj:
        raise Http404
    res_dict = {'submodul': submodul_obj,
                'project':project_obj}
    return render(request,'backend/Project/submodul/manage.html',res_dict)


def configration_preview(request,project_id,submodul_id):
    '''配置文件总览'''
    project_obj = models.Project.objects.filter(id=project_id).first()
    submodul_obj = models.SubModul.objects.filter(id=submodul_id).first()
    if not project_obj or not submodul_obj:
        raise Http404
    res_dict = {'project': project_obj,
                'submodul':submodul_obj,
                'query_set': models.Configuration.objects.filter(submodul=submodul_obj)}
    return render(request, 'backend/Project/submodul/configration/preview.html', res_dict)


def configration_add(request,project_id,submodul_id):
    '''新增配置文件'''
    project_obj = models.Project.objects.filter(id=project_id).first()
    submodul_obj = models.SubModul.objects.filter(id=submodul_id).first()
    if not project_obj or not submodul_obj:
        raise Http404
    if request.method == 'GET':
        initial = {'submodul_id': submodul_obj.id}
        form_obj = ConfigrationCreateForm(initial=initial)
    elif request.method == 'POST':
        form_obj = ConfigrationCreateForm(request.POST)
        if form_obj.is_valid():
            models.Configuration.objects.create(**form_obj.cleaned_data)
            kwargs = {'project_id': project_obj.id,'submodul_id':submodul_obj.id}
            redirect_url = reverse('configration_preview', kwargs=kwargs)
            return redirect(redirect_url)
    res_dict = {'project': project_obj,
                'submodul': submodul_obj,
                'form_obj': form_obj}
    return render(request, 'backend/Project/submodul/configration/change.html', res_dict)


def configration_change(request,project_id,submodul_id,configration_id):
    '''修改配置文件'''
    project_obj = models.Project.objects.filter(id=project_id).first()
    submodul_obj = models.SubModul.objects.filter(id=submodul_id).first()
    configration_obj = models.Configuration.objects.filter(id=configration_id).first()
    if not project_obj or not submodul_obj or not configration_obj:
        raise Http404
    if request.method == 'GET':
        initial = {'id': configration_obj.id,
                   'file_path': configration_obj.file_path,
                   'file_type': configration_obj.file_type,
                   'description': configration_obj.description,
                   'config': configration_obj.config,
                   'submodul_id':submodul_obj.id}
        form_obj = ConfigrationEditForm(initial=initial)
    elif request.method == 'POST':
        form_obj = ConfigrationEditForm(request.POST)
        if form_obj.is_valid():
            for field, value in form_obj.cleaned_data.items():
                setattr(configration_obj,field,value)
            configration_obj.save()
            kwargs = {'project_id': project_obj.id, 'submodul_id': submodul_obj.id}
            redirect_url = reverse('configration_preview', kwargs=kwargs)
            return redirect(redirect_url)
    res_dict = {'project': project_obj,
                'submodul': submodul_obj,
                'form_obj': form_obj}
    return render(request, 'backend/Project/submodul/configration/change.html', res_dict)


def display_conf(request):
    '''展示配置文件'''
    res_dict = {'status': True, 'error': None, 'data': None}
    configration_obj = models.Configuration.objects.filter(id=request.GET.get('nid')).first()
    if not configration_obj:
        res_dict['status'] = False
        res_dict['error'] = '系统繁忙，请稍候再试'
    else:
        conf = {'file_path':configration_obj.file_path,
                'config': configration_obj.config,
                'file_type': configration_obj.file_type}
        res_dict['data'] = conf
    return HttpResponse(json.dumps(res_dict))


def host_preview(request, project_id, submodul_id):
    '''子模块关联主机总览'''
    project_obj = models.Project.objects.filter(id=project_id).first()
    submodul_obj = models.SubModul.objects.filter(id=submodul_id).first()
    if not project_obj or not submodul_obj:
        raise Http404
    res_dict = {'project': project_obj,
                'submodul': submodul_obj,
                'query_set': models.SubModul2Host.objects.filter(submodul=submodul_obj).values('id','host__ip_address','host__description')}
    return render(request, 'backend/Project/submodul/host/preview.html', res_dict)


def host_add(request, project_id, submodul_id):
    '''新增子模块关联主机'''
    project_obj = models.Project.objects.filter(id=project_id).first()
    submodul_obj = models.SubModul.objects.filter(id=submodul_id).first()
    if not project_obj or not submodul_obj:
        raise Http404
    if request.method == 'GET':
        initial = {'submodul_id': submodul_obj.id,
                   'source_file':submodul_obj.source_file,
                   'target_file': submodul_obj.target_file,
                   'backup_command': submodul_obj.backup_command,
                   'stop_command': submodul_obj.stop_command,
                   'start_command': submodul_obj.start_command,
                   'clean_old_file_command': submodul_obj.clean_old_file_command}
        form_obj = SubModul2HostCreateForm(initial=initial)
    elif request.method == 'POST':
        post_data = {'submodul_id': submodul_obj.id,
                     'host': request.POST.get('host')}
        if not request.POST.get('is_customize'):    # 使用submodul中的配置
            post_data['source_file'] = submodul_obj.source_file
            post_data['target_file'] = submodul_obj.target_file
            post_data['backup_command'] = submodul_obj.backup_command
            post_data['stop_command'] = submodul_obj.stop_command
            post_data['start_command'] = submodul_obj.start_command
            post_data['clean_old_file_command'] = submodul_obj.clean_old_file_command
        else:    # 进行单独配置
            post_data['is_customize'] = True
            post_data['source_file'] = request.POST.get('source_file')
            post_data['target_file'] = request.POST.get('target_file')
            post_data['backup_command'] = request.POST.get('backup_command')
            post_data['stop_command'] = request.POST.get('stop_command')
            post_data['start_command'] = request.POST.get('start_command')
            post_data['clean_old_file_command'] = request.POST.get('clean_old_file_command')
        form_obj = SubModul2HostCreateForm(post_data)
        if form_obj.is_valid():
            models.SubModul2Host.objects.create(**form_obj.cleaned_data)
            kwargs = {'project_id': project_obj.id, 'submodul_id': submodul_obj.id}
            redirect_url = reverse('submodul2host_preview', kwargs=kwargs)
            return redirect(redirect_url)
    res_dict = {'project': project_obj,
                'submodul': submodul_obj,
                'form_obj': form_obj}
    return render(request, 'backend/Project/submodul/host/change.html', res_dict)


def host_change(request, project_id, submodul_id,submodul2host_id):
    '''修改子模块关联主机'''
    project_obj = models.Project.objects.filter(id=project_id).first()
    submodul_obj = models.SubModul.objects.filter(id=submodul_id).first()
    submodul2host_obj = models.SubModul2Host.objects.filter(id=submodul2host_id).first()
    if not project_obj or not submodul_obj or not submodul2host_obj:
        raise Http404
    if request.method == 'GET':
        initial = {'id': submodul2host_obj.id,
                   'submodul_id': submodul2host_obj.submodul.id,
                   'host': submodul2host_obj.host,
                   'is_customize': submodul2host_obj.is_customize,
                   'source_file':submodul2host_obj.source_file,
                   'target_file': submodul2host_obj.target_file,
                   'backup_command': submodul2host_obj.backup_command,
                   'stop_command': submodul2host_obj.stop_command,
                   'start_command': submodul2host_obj.start_command,
                   'clean_old_file_command': submodul2host_obj.clean_old_file_command}
        form_obj = SubModul2HostEditForm(initial=initial)
    elif request.method == 'POST':
        post_data = {'id': submodul2host_obj.id,
                     'submodul_id': submodul_obj.id,
                     'host': request.POST.get('host'),}
        if not request.POST.get('is_customize'):    # 使用submodul中的配置
            post_data['source_file'] = submodul_obj.source_file
            post_data['target_file'] = submodul_obj.target_file
            post_data['backup_command'] = submodul_obj.backup_command
            post_data['stop_command'] = submodul_obj.stop_command
            post_data['start_command'] = submodul_obj.start_command
            post_data['clean_old_file_command'] = submodul_obj.clean_old_file_command
        else:    # 进行单独配置
            post_data['is_customize'] = request.POST.get('is_customize')
            post_data['source_file'] = request.POST.get('source_file')
            post_data['target_file'] = request.POST.get('target_file')
            post_data['backup_command'] = request.POST.get('backup_command')
            post_data['stop_command'] = request.POST.get('stop_command')
            post_data['start_command'] = request.POST.get('start_command')
            post_data['clean_old_file_command'] = request.POST.get('clean_old_file_command')
        form_obj = SubModul2HostEditForm(post_data)
        if form_obj.is_valid():
            for field, value in form_obj.cleaned_data.items():
                setattr(submodul2host_obj,field,value)
                submodul2host_obj.save()
            kwargs = {'project_id': project_obj.id, 'submodul_id': submodul_obj.id}
            redirect_url = reverse('submodul2host_preview', kwargs=kwargs)
            return redirect(redirect_url)

    res_dict = {'project': project_obj,
                'submodul': submodul_obj,
                'form_obj': form_obj}
    return render(request, 'backend/Project/submodul/host/change.html', res_dict)

